<template>
  <list :style="{ width: `${defaultProps.width}rpx`, height: `${defaultProps.height}rpx` }">
    <header
      v-if="_showHeader"
      class="tableBox flex flex-row"
      :style="{
        width: `${defaultProps.width}rpx`,
        height: `${defaultProps.headerHeight}rpx`,
      }"
    >
      <scroller
        ref="scrolleHead"
        :scrollable="false"
        class="tableRight flex flex-row flex-1"
        scroll-direction="horizontal"
      >
        <tm-row v-if="props.showHeader" :transprent="true" :width="totalTableWidth" :column="_data.header.length">
          <tm-col
            v-for="(item, index) in _data.header"
            :key="index"
            _class="flex flex-row flex-row-center-center"
            :text="item.opts?.light ?? false"
            :height="props.headerHeight"
            :color="item.opts?.color ?? 'primary'"
            :transprent="false"
            @click="headerClick(item, index)"
          >
            <view
              :user-interaction-enabled="false"
              :style="{
                width:
                  (item.opts?.sort ?? false
                    ? totalTableWidth / _data.header.length - 60
                    : totalTableWidth / _data.header.length - 60) + 'rpx',
              }"
            >
              <tm-text
                _class="text-overflow-2 text-align-center"
                :line-height="0"
                :font-size="item.opts?.fontSize ?? 0"
                :color="item.opts?.fontColor ?? ''"
                :label="item.name"
              ></tm-text>
            </view>
            <tm-icon
              v-if="item.opts?.sort ?? false"
              :user-interaction-enabled="false"
              name="tmicon-sort"
              :font-size="26"
            ></tm-icon>
          </tm-col>
        </tm-row>
      </scroller>
    </header>
    <cell class="tableBox" :style="{ width: `${defaultProps.width}rpx` }">
      <scroller
        ref="scrollerRight"
        class="tableRight"
        scroll-direction="horizontal"
        :style="{ width: `${defaultProps.width}rpx` }"
      >
        <view v-for="(item, index) in _maxrows" :key="item" :style="{ width: totalTableWidth + 'rpx' }">
          <view>
            <tm-divider v-if="props.showBottomBorder && !_stripe" color="grey-5" :margin="[0, 0]"></tm-divider>
          </view>

          <tm-row
            :color="_stripe ? (index % 2 ? 'grey-5' : 'white') : 'white'"
            :width="totalTableWidth"
            :column="_data.header.length"
            :transprent="false"
          >
            <tm-col
              v-for="(item2, index2) in _data.header.length"
              :key="item2"
              :col="1"
              :text="getOptsCellStyle(index2, index)?.light ?? false"
              :height="props.cellHeight"
              :color="getOptsCellStyle(index2, index)?.color ?? ''"
              :transprent="_stripe"
              _class="flex flex-row flex-row-center-center"
              @click="cellClick(index2, index)"
            >
              <view
                v-if="((_rows[index2] ?? [])[index].opts?.type ?? 'text') == 'button'"
                :user-interaction-enabled="false"
                class="flex-1"
              >
                <tm-button
                  :font-size="getOptsCellStyle(index2, index)?.fontSize ?? 26"
                  :color="getOptsCellStyle(index2, index)?.fontColor ?? 'primary'"
                  :label="(_rows[index2] ?? [])[index].value ?? '-'"
                  :margin="[10, 10]"
                  :height="props.cellHeight - 20"
                  size="mini"
                  block
                ></tm-button>
              </view>
              <tm-text
                v-else
                :user-interaction-enabled="false"
                :font-size="getOptsCellStyle(index2, index).fontSize"
                :line-height="0"
                :color="getOptsCellStyle(index2, index).fontColor"
                :label="(_rows[index2] ?? [])[index].value ?? '-'"
              ></tm-text>
            </tm-col>
          </tm-row>
        </view>
      </scroller>
    </cell>
  </list>
</template>

<script setup lang="ts">
import { computed, ref, Ref, getCurrentInstance, onMounted, nextTick, onBeforeUnmount, PropType, watch } from 'vue'
import type { headresItem, cellItem, dataTypeArray, FixedItemType } from '../interface'
import { tableDataType, tabaleCellStyleType, defaultCellStyle, tabaleCellData, headerType } from './newInterface'
import tmIcon from '../tm-icon/tm-icon.vue'
import tmText from '../tm-text/tm-text.vue'
import tmSheet from '../tm-sheet/tm-sheet.vue'
import tmButton from '../tm-button/tm-button.vue'
import tmRow from '../tm-row/tm-row.vue'
import tmCol from '../tm-col/tm-col.vue'
import tmDivider from '../tm-divider/tm-divider.vue'
import { cutomProps } from './cutomProps'
const Binding = uni.requireNativePlugin('bindingx')
const proxy = getCurrentInstance()?.proxy ?? null
const props = defineProps({ ...cutomProps })

let bindingx_token: any = null
const defaultProps = computed(() => {
  return {
    width: props.width,
    height: props.height,
    cellHeight: props.cellHeight,
    headerHeight: props.headerHeight,
    showFixed: props.showFixed,
  }
})
const _fixedKey = ref('')
const _showBottomBorder = computed(() => props.showBottomBorder)
const _showHeader = computed(() => props.showHeader)

const emits = defineEmits(['rowClick'])

const _data: Ref<tableDataType> = ref({
  fields: {
    columns: [],
  },
  header: [],
  data: [],
})
const sortType = ref('none')
const _stripe = computed(() => props.stripe)
const totalTableWidth = computed(() => {
  let d = props.cellWidth * _data.value.header.length

  if (d <= props.width) d = props.width
  return d
})
const _rows: Ref<Array<Array<tabaleCellData>>> = ref([])
let _rows_back: Array<Array<tabaleCellData>> = []
const _maxrows = ref(0)

onMounted(() => {
  // _rows.value = chuliRows(_data.value.data)
  // _rows_back = uni.$tm.u.deepClone(_rows.value)
  setTimeout(function () {
    bindingXscroll()
  }, 200)
})
watch(
  [() => props.tableData],
  () => {
    _data.value = { ...props.tableData }
    _rows.value = chuliRows(uni.$tm.u.deepClone(props.tableData.data))
    _rows_back = uni.$tm.u.deepClone(_rows.value)
  },
  { deep: true, immediate: true }
)

function chuliRows(
  bigdata: Array<{
    [key: string]: any
  }>
) {
  let d: Array<Array<tabaleCellData>> = []
  let dlen: number[] = []
  let dstyle: Array<
    Array<{
      [key: string]: tabaleCellStyleType
    }>
  > = []
  if (!bigdata) {
    bigdata = []
  }
  _data.value.data = bigdata.map((el) => {
    let ptps: {
      [key: string]: tabaleCellStyleType
    } = el['opts'] ?? {}
    _data.value.header.forEach((ielem) => {
      if (ptps[ielem.field]) {
        ptps[ielem.field] = { ...(ptps[ielem.field] ?? {}) }
      } else {
        ptps[ielem.field] = {}
      }
    })
    el['opts'] = ptps
    return el
  })

  _data.value.header.forEach((el) => {
    let pd: Array<tabaleCellData> = []
    pd = _data.value.data.map((ele: { [key: string]: any }) => {
      let isasync = el?.opts?.asyncStyleCell ?? false
      return {
        value: ele[el.field] ?? '-',
        opts: {
          ...defaultCellStyle,
          ...{
            color: isasync === true ? el.opts?.color ?? 'white' : 'white',
            fontColor: isasync === true ? el.opts?.fontColor ?? 'black' : '',
            light: isasync === true ? el.opts?.light ?? false : false,
          },
          ...ele['opts'][el.field],
        },
      }
    })

    d.push(pd)
    dlen.push(pd.length)
  })
  _maxrows.value = Math.max(...(dlen.length ? dlen : [0, 0]))
  return d
}

function getOptsCellStyle(index1: number, index2: number) {
  let d = (_rows.value[index1] ?? [])[index2].opts ?? { ...defaultCellStyle }
  return d
}

function cellClick(index1: number, index2: number) {
  let dp = (_rows.value[index1] ?? [])[index2].value ?? ''
  /**row,col,value */
  emits('rowClick', index2, index1, dp)
}

function sort(data: Array<Array<tabaleCellData>>, index: number, type = 'none', callback: Function) {
  uni.showLoading({
    title: '...',
    mask: true,
  })
  let d = data[index]
  // 排序
  if (type == 'none') {
    data = uni.$tm.u.deepClone(_rows_back)
  }

  //降序
  if (type == 'desc') {
    let dbiaoji = []
    for (let i = 0; i < d.length; i++) {
      dbiaoji.push(i)
    }
    d = d.map((el, iof) => {
      el['__ids'] = iof
      return el
    })
    d.sort((a, b) => Number(a.value) - Number(b.value))
    let pd: Array<Array<tabaleCellData>> = []
    data.forEach((element, index2) => {
      let p: Array<tabaleCellData> = []
      if (index2 !== index) {
        d.forEach((el, index3) => {
          let nm = el['__ids']
          p.push(element[nm])
        })
      } else {
        p = d
      }
      pd.push(p)
    })

    data = pd
  }
  //升序。
  if (type == 'asce') {
    let pd: Array<Array<tabaleCellData>> = []
    data.forEach((element, index2) => {
      let p: Array<tabaleCellData> = []
      p = [...element.reverse()]
      pd.push(p)
    })

    data = pd
  }

  nextTick(() => {
    if (callback) {
      callback(data)
    }
    uni.hideLoading()
  })
}

function headerClick(item: headerType, index: number) {
  if (item.opts?.sort ?? false) {
    let d = uni.$tm.u.deepClone(_rows.value)
    if (sortType.value == 'none') {
      sortType.value = 'desc'
    } else if (sortType.value == 'desc') {
      sortType.value = 'asce'
    } else if (sortType.value == 'asce') {
      sortType.value = 'none'
    }
    sort(d, index, sortType.value, (ds: Array<Array<tabaleCellData>>) => {
      _rows.value = [...ds]
    })
  }
}

onBeforeUnmount(() => unbindXscroll())

function bindingXscroll() {
  let scroller_right = proxy.$refs.scrollerRight
  let scroller_right_head = proxy.$refs.scrolleHead
  nextTick(() => {
    scroller_right = scroller_right.ref
    scroller_right_head = scroller_right_head.ref
    Binding.bind(
      {
        eventType: 'scroll',
        anchor: scroller_right,
        props: [
          {
            element: scroller_right_head,
            property: 'scroll.contentOffsetX',
            expression: 'x+0',
          },
        ],
      },
      (e) => {
        bindingx_token = e.token
      }
    )
  })
}

function unbindXscroll() {
  if (bindingx_token) {
    Binding.unbind({
      token: bindingx_token,
      eventType: 'scroll',
    })
  }
}

function getEl(el: HTMLElement) {
  if (typeof el === 'string' || typeof el === 'number') return el
  if (WXEnvironment) {
    return el.ref
  } else {
    return el instanceof HTMLElement ? el : el.$el
  }
}
</script>

<style></style>
